package com.bjsxt.controller.doctor;


import cn.hutool.core.date.DateUtil;
import com.bjsxt.constants.Constants;
import com.bjsxt.controller.BaseController;
import com.bjsxt.domain.Dept;
import com.bjsxt.domain.Patient;
import com.bjsxt.domain.Registration;
import com.bjsxt.dto.PatientDto;
import com.bjsxt.dto.RegistrationDto;
import com.bjsxt.dto.RegistrationFormDto;
import com.bjsxt.dto.RegistrationQueryDto;
import com.bjsxt.service.DeptService;
import com.bjsxt.service.PatientService;
import com.bjsxt.service.RegistrationService;
import com.bjsxt.service.SchedulingService;
import com.bjsxt.utils.IdGeneratorSnowflake;
import com.bjsxt.utils.ShiroSecurityUtils;
import com.bjsxt.vo.AjaxResult;
import com.bjsxt.vo.DataGridView;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import java.util.Collections;
import java.util.List;

/**
 * 挂号管理控制层
 */
@Log4j2
@RestController
@RequestMapping("doctor/registration")
public class RegistrationController extends BaseController {

    @Reference
    private RegistrationService registrationService;

    @Reference
    private SchedulingService schedulingService;

    @Reference
    private PatientService patientService;

    @Autowired
    private DeptService deptService;

    /**
     * 分页查询出有排班的部门列表
     *
     * @param registrationQueryDto
     * @return
     */
    @GetMapping("listDeptForScheduling")
    @HystrixCommand
    public AjaxResult listDeptForScheduling(RegistrationQueryDto registrationQueryDto) {
        Long deptId = registrationQueryDto.getDeptId();
        @NotBlank(message = "挂号日期不能为空") String schedulingDay = registrationQueryDto.getSchedulingDay();
        @NotBlank(message = "挂号类型不能为空") String schedulingType = registrationQueryDto.getSchedulingType();
        @NotBlank(message = "挂号时段不能为空") String subsectionType = registrationQueryDto.getSubsectionType();
        List<Long> deptIds = this.schedulingService.queryHasSchedulingDeptIds(deptId, schedulingDay, schedulingType, subsectionType);
        if (deptIds == null || deptIds.size() == 0) {
            return AjaxResult.success(Collections.EMPTY_LIST);
        }
        List<Dept> list = this.deptService.listDeptByDeptIds(deptIds);
        return AjaxResult.success(list);
    }

    /**
     * 根据身份证号查询患者信息
     *
     * @param idCard
     * @return
     */
    @GetMapping("getPatientByIdCard/{idCard}")
    @HystrixCommand
    public AjaxResult getPatientByIdCard(@Validated @PathVariable String idCard) {
        Patient patient = this.patientService.getPatientByIdCard(idCard);
        if (null == patient) {
            return AjaxResult.fail(idCard + "对应的患者不存在，请在下面新建患者信息");
        } else {
            return AjaxResult.success(patient);
        }
    }

    /**
     * 添加挂号信息
     *
     * @param registrationFormDto
     * @return
     */
    @PostMapping("addRegistration")
    @HystrixCommand
    public AjaxResult addRegistration(@Validated @RequestBody RegistrationFormDto registrationFormDto) {
        PatientDto patientDto = registrationFormDto.getPatientDto();
        RegistrationDto registrationDto = registrationFormDto.getRegistrationDto();
        Patient patient = null;
        //保存患者信息【isNotBlank判断字符串是否不为空且不为0且不由空白符whitespace构成】
        if (StringUtils.isNotBlank(patientDto.getPatientId())) {
            patientDto.setPatientId(IdGeneratorSnowflake.generatorIdWithProfix("HZ"));
            patientDto.setSimpleUser(ShiroSecurityUtils.getCurrentSimpleUser());
            patient = patientService.addPatient(patientDto);
        } else {
            patient = this.patientService.getPatientById(patientDto.getPatientId());
        }
        if (null == patient) {
            return AjaxResult.fail("当前患者id不存在，请确认后再提交");
        }
        //保存挂号信息
        Dept dept = deptService.getOne(registrationDto.getDeptId());
        registrationDto.setRegId(IdGeneratorSnowflake.generatorIdWithProfix("GH"));
        registrationDto.setPatientId(patient.getPatientId());
        registrationDto.setPatientName(patient.getName());
        registrationDto.setRegNumber(dept.getRegNumber() + 1);
        registrationDto.setVisitDate(registrationDto.getVisitDate().substring(0, 10));
        registrationDto.setSimpleUser(ShiroSecurityUtils.getCurrentSimpleUser());
        this.registrationService.addRegistration(registrationDto);
        //修改部门挂号信息编号
        dept.setRegNumber(dept.getRegNumber() + 1);
        this.deptService.updateDeptRegNumber(dept.getDeptId(), dept.getRegNumber());
        return AjaxResult.success("添加成功" + registrationDto.getRegId());
    }

    /**
     * 分页查询挂号信息
     */
    @GetMapping("queryRegistrationForPage")
    @HystrixCommand
    public AjaxResult queryRegistrationForPage(RegistrationDto registrationDto) {
        DataGridView gridView = this.registrationService.queryRegistrationForPage(registrationDto);
        return AjaxResult.success("查询成功", gridView.getData(), gridView.getTotal());
    }

    /**
     * 分页查询挂号信息【默认为当天】
     *
     * @return
     */
    @GetMapping("queryOtherRegistrationForPage")
    @HystrixCommand
    public AjaxResult queryOtherRegistrationForPage(RegistrationDto registrationDto) {
        if (registrationDto.getBeginTime() == null || registrationDto.getEndTime() == null) {
            registrationDto.setVisitDate(DateUtil.format(DateUtil.date(), "yyyy-MM-dd"));
        }
        DataGridView dataGridView = this.registrationService.queryRegistrationForPage(registrationDto);
        return AjaxResult.success("查询成功", dataGridView.getData(), dataGridView.getTotal());
    }

    /**
     * 收费
     * String REG_STATUS_0 = "0"; //待支付
     * String REG_STATUS_1 = "1"; //待就诊
     * String REG_STATUS_2 = "2"; //就诊中
     * String REG_STATUS_3 = "3"; //就诊完成
     * String REG_STATUS_4 = "4"; //已退号
     * String REG_STATUS_5 = "5"; //已作废
     *
     * @param regId
     * @return
     */
    @PostMapping("collectFee/{regId}")
    @HystrixCommand
    public AjaxResult collectFee(@Validated @PathVariable String regId) {
        //查询挂号单
        Registration registration = this.registrationService.queryRegistrationByRegId(regId);
        if (registration == null) {
            return AjaxResult.fail("当前挂号单【" + regId + "】对应的挂号单不存在，请核对后再查询");
        }
        //如果挂号单的状态不是未收费
        if (!registration.getRegistrationStatus().equals(Constants.REG_STATUS_0)) {
            return AjaxResult.fail("当前挂号单【" + regId + "】状态不是未收费状态，不能进行收费");
        }
        //收费并更新挂号单的状态
        registration.setRegistrationStatus(Constants.REG_STATUS_1);
        return AjaxResult.toAjax(this.registrationService.updateRegistrationById(registration));
    }

    /**
     * 作废
     *
     * @param regId
     * @return
     */
    @PostMapping("doInvalid/{regId}")
    @HystrixCommand
    public AjaxResult doInvalid(@Validated @PathVariable String regId) {
        //查询挂号单
        Registration registration = this.registrationService.queryRegistrationByRegId(regId);
        if (registration == null) {
            return AjaxResult.fail("当前挂号单【" + regId + "】对应的挂号单不存在，请核对后再查询");
        }
        //如果挂号单的状态不是未收费
        if (!registration.getRegistrationStatus().equals(Constants.REG_STATUS_0)) {
            return AjaxResult.fail("当前挂号单【" + regId + "】状态不是未收费状态，不能进行收费");
        }
        //作废并更新挂号单的状态
        registration.setRegistrationStatus(Constants.REG_STATUS_5);
        return AjaxResult.toAjax(this.registrationService.updateRegistrationById(registration));
    }

    /**
     * 退号
     *
     * @param regId
     * @return
     */
    @PostMapping("doReturn/{regId}")
    @HystrixCommand
    public AjaxResult doReturn(@Validated @PathVariable String regId) {
        Registration registration = this.registrationService.queryRegistrationByRegId(regId);
        if (null == registration) {
            return AjaxResult.fail("当前挂号单【" + regId + "】对应的挂号单不存在，请核对后再查询");
        }
        //如果挂号单的状态不是未收费
        if (!registration.getRegistrationStatus().equals(Constants.REG_STATUS_1)) {
            return AjaxResult.fail("当前挂号单【" + regId + "】的状态不是待就诊状态，不能退号");
        }
        //收费，更新挂号单的状态
        registration.setRegistrationStatus(Constants.REG_STATUS_4);
        return AjaxResult.toAjax(this.registrationService.updateRegistrationById(registration));
    }
}
